﻿using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using KinonekoSoftware.ArkSpark.Core;
using KinonekoSoftware.ArkSpark.Services.Highlighting;
using KinonekoSoftware.ArkSpark.Services.Highlights;
using KinonekoSoftware.Extensions.Ioc;

namespace KinonekoSoftware.ArkSpark.Helpers
{
    /// <summary>
    /// 实现TextBlock的高亮显示。
    /// </summary>
    public static class Highlight
    {
        public static readonly DependencyProperty HighlightSourceProperty = DependencyProperty.RegisterAttached(
                                                                                                                "HighlightSource",
                                                                                                                typeof(IList<IHighlightToken>),
                                                                                                                typeof(Highlight),
                                                                                                                new UIPropertyMetadata(default(IList<IHighlightToken>), OnHighlightSourceChanged));

        public static readonly DependencyProperty HighlightInfoChangedProperty = DependencyProperty.RegisterAttached(
                                                                                            "HighlightInfoChanged",
                                                                                            typeof(int), 
                                                                                            typeof(Highlight), 
                                                                                            new PropertyMetadata(default(int), OnHighlightInfoChanged));

        public static void SetHighlightInfoChanged(TextBlock element, int value)
        {
            element.SetValue(HighlightInfoChangedProperty, value);
        }

        public static int GetHighlightInfoChanged(TextBlock element)
        {
            return (int)element.GetValue(HighlightInfoChangedProperty);
        }
        
        private static void OnHighlightInfoChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is TextBlock visual                               &&
                visual.DataContext is IHighlightDataContext context)
            {
                HighlightThis(visual, context, context.GetHighlightGlossaries());
            }
        }

        private static void OnHighlightSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is TextBlock visual                               &&
                visual.DataContext is IHighlightDataContext context &&
                e.NewValue is IList<IHighlightToken> highlightGlossaries)
            {
                HighlightThis(visual, context, highlightGlossaries);
            }
           
        }

        private static void HighlightThis(TextBlock visual, IHighlightDataContext context, IList<IHighlightToken> highlightGlossaries)
        {
            if(highlightGlossaries.Count == 0)
            {
                return;
            }

            if (highlightGlossaries.Count == 1 && !highlightGlossaries[0].Segment.IsMatch)
            {
                visual.Text = highlightGlossaries[0].Name;
            }
            else
            {
                var style = HighlightStyle ?? DefaultHighlightVisualStyle.Instance;
                style.reStyle(visual, highlightGlossaries, context.Content);
            }
        }


        public static void SetHighlightSource(DependencyObject element, IList<IHighlightToken> value)
        {
            element.SetValue(HighlightSourceProperty, value);
        }

        public static IList<IHighlightToken> GetHighlightSource(DependencyObject element)
        {
            return (IList<IHighlightToken>)element.GetValue(HighlightSourceProperty);
        }


        public static IHighlightVisualStyle            HighlightStyle    { get; set; }
    }
}